import { track, trigger,pauseTracking, resumeTracking} from "./effect.js";
import { TrackOpTypes, TriggerOpTypes } from "./operations.js";
import { reactive } from "./reactive.js";
import { hasChanged, isObject } from "./utils.js";

const arrayInstrumentactions = {};
const RAW = Symbol("raw");
["includes", "indexOf", "lastIndexOf"].forEach((key) => {
  arrayInstrumentactions[key] = function (...args) {
    const resuslt = Array.prototype[key].apply(this, args);
    if (resuslt < 0 || resuslt === false) {
      console.log(`数组中不存在${args[0]}`);
      return Array.prototype[key].apply(this[RAW], args);
    }
    return resuslt;
  };
});
["push", "pop", "shift", "unshift", "splice"].forEach((key) => {
  arrayInstrumentactions[key] = function (...args) {
    pauseTracking();// --暂停依赖收集
    const resuslt = Array.prototype[key].apply(this, args);
    resumeTracking();// --恢复依赖收集
    return resuslt;
  };
});

function get(target, key, reactiver) {
  if (key === RAW) {
    return target;
  }
  track(target, TrackOpTypes.Get, key);
  if (arrayInstrumentactions.hasOwnProperty(key) && Array.isArray(target)) {
    return arrayInstrumentactions[key];
  }
  const resuslt = Reflect.get(target, key, reactiver);
  if (isObject(resuslt)) {
    return reactive(resuslt);
  }
  return resuslt;
}
function set(target, key, value, reactiver) {
  console.log("设置属性");
  const type = target.hasOwnProperty(key)
    ? TriggerOpTypes.Set
    : TriggerOpTypes.Add;
  // -- 指有变化，或者类型是新增的时候派发更新
  const oldValue = target[key]; // --取到的旧值有问题???
  const oldLen = Array.isArray(target) ? target.length : undefined;
  const resuslt = Reflect.set(target, key, value, reactiver);
  if (!resuslt) return resuslt;
  const newLen = Array.isArray(target) ? target.length : undefined;
  if (hasChanged(value, oldValue) || type === TriggerOpTypes.Add) {
    if (Array.isArray(target) && oldLen !== newLen) {
      if (key !== "length") {console.log("修改数组长度");
        trigger(target, TriggerOpTypes.Set, "length");
      } else {console.log("修改数组长度");
        for (let i = newLen; i < oldLen; i++) {
          trigger(target, TriggerOpTypes.Delete, i.toString());
        }
      }
    }
  }
  console.log(resuslt)
  return resuslt;
}
function deleteProperty(target, key) {
  console.log("删除属性");
  const hasKey = target.hasOwnProperty(key);
  const resuslt = Reflect.deleteProperty(target, key);
  if (hasKey && resuslt) {
    trigger(target, TriggerOpTypes.Delete, key);
  }
  return resuslt;
}

function has(target, key) {
  track(target, TrackOpTypes.Has, key);
  return Reflect.has(target, key);
}

function ownKeys(target) {
  track(target, TrackOpTypes.ITERATE);
  return Reflect.ownKeys(target);
}
export const handlers = {
  get,
  set,
  has,
  ownKeys,
  deleteProperty,
};
